﻿using System;
using System.Reflection;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using CommonTypes.Server;
using CommonTypes.Client;
using Client.Model;
using System.Windows.Forms;

namespace Client
{
    public static class MessageDissemination
    {
        public static void disseminateMessage(MethodInfo methodToCall, ClientData clientData, ArrayList lastingClients, Object[] args, bool sendToTwo)
        {
            DisseminateMessageAsyncDel dissDel = new DisseminateMessageAsyncDel(DisseminateMessageAsync);

            dissDel.BeginInvoke(methodToCall, clientData, lastingClients, args, sendToTwo, null, null);
        }

        private delegate void DisseminateMessageAsyncDel(MethodInfo methodToCall, ClientData clientData, ArrayList lastingClients, Object[] args, bool sendToTwo);

        private static void DisseminateMessageAsync(MethodInfo methodToCall, ClientData clientData, ArrayList lastingClients, Object[] args, bool sendToTwo)
        {
            ArrayList clientIds = new ArrayList();
            Random random = new Random();

            //get Clients addresses and proxies
            if (lastingClients.Count > 2 && sendToTwo)
            {
                int client1Index = random.Next(lastingClients.Count - 1);
                int client2Index = random.Next(lastingClients.Count - 1);
                while (client1Index == client2Index)
                    client2Index = random.Next(lastingClients.Count - 1);

                clientIds.Add(lastingClients[client1Index]);
                clientIds.Add(lastingClients[client2Index]);
            }
            else if (lastingClients.Count == 2 && sendToTwo)
            {
                clientIds.Add(lastingClients[0]);
                clientIds.Add(lastingClients[1]);
            }
            else if (lastingClients.Count == 1 || (!sendToTwo))
            {              
                clientIds.Add(lastingClients[0]);
            }

            //invoke method on clients
            for (int index = 0; index < clientIds.Count; index++)
            {
                IClientToServer server = clientData.GetRandomServer();
                String clientAddress = server.ResolveClient((String)clientIds[index]);
                IClientToClient clientToClient = (IClientToClient)Activator.GetObject(typeof(IClientToClient), clientAddress + "/ClientToClient");

                try
                {
                    methodToCall.Invoke(clientToClient, args);
                }
                catch
                {
                    continue;
                }
            }
        }
    }
}
